package com.cmc6.notify.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cmc6.common.exception.BaseBizCodeEnum;
import com.cmc6.common.model.dto.NotEmptyIdSet;
import com.cmc6.common.model.dto.NotNullId;
import com.cmc6.common.model.entity.NotifyDO;
import com.cmc6.common.model.entity.NotifyRefUserDO;
import com.cmc6.common.service.NotifyRefUserService;
import com.cmc6.common.util.ApiResult;
import com.cmc6.common.util.KafkaUtil;
import com.cmc6.common.util.UserUtil;
import com.cmc6.notify.mapper.NotifyMapper;
import com.cmc6.notify.model.dto.NotifyPageDTO;
import com.cmc6.notify.model.vo.NotifyInfoByIdVO;
import com.cmc6.notify.model.vo.NotifyPageVO;
import com.cmc6.notify.service.NotifyService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.Date;
import java.util.Set;

@Service
public class NotifyServiceImpl extends ServiceImpl<NotifyMapper, NotifyDO> implements NotifyService {

    @Resource
    NotifyRefUserService notifyRefUserService;

    /**
     * 分页排序查询：当前用户，通知
     */
    @Override
    public Page<NotifyPageVO> userPage(NotifyPageDTO dto) {

        Long userIdSafe = UserUtil.getCurrentUserIdSafe();

        Page<NotifyPageVO> page = dto.getPage();

        return baseMapper.userPage(page, dto, userIdSafe);
    }

    /**
     * 当前用户：已读通知
     */
    @Override
    public String userRead(NotEmptyIdSet notEmptyIdSet) {
        return userReadByIdSet(notEmptyIdSet.getIdSet());
    }

    /**
     * 当前用户：全部已读
     */
    @Override
    public String userAllRead() {
        return userReadByIdSet(null);
    }

    /**
     * 当前用户：通过 notifyIdSet，已读通知，为 null，则已读全部
     */
    private String userReadByIdSet(Set<Long> notifyIdSet) {

        Long userIdSafe = UserUtil.getCurrentUserIdSafe();

        notifyRefUserService.lambdaUpdate().eq(NotifyRefUserDO::getUserId, userIdSafe)
            .in(CollUtil.isNotEmpty(notifyIdSet), NotifyRefUserDO::getNotifyId, notifyIdSet)
            .eq(NotifyRefUserDO::getReadFlag, false).set(NotifyRefUserDO::getReadFlag, true)
            .set(NotifyRefUserDO::getUpdateTime, new Date()).update();

        // socket，有新的通知
        KafkaUtil.refreshNoReadNotifyCount(Collections.singleton(userIdSafe));

        return BaseBizCodeEnum.API_RESULT_OK.getMsg();
    }

    /**
     * 获取：当前用户，未读通知总和
     */
    @Override
    public long userNoReadCount() {

        Long userIdSafe = UserUtil.getCurrentUserIdSafe();

        return notifyRefUserService.lambdaQuery().eq(NotifyRefUserDO::getUserId, userIdSafe)
            .eq(NotifyRefUserDO::getReadFlag, false).count();
    }

    /**
     * 通过主键id，查看详情
     */
    @Override
    public NotifyInfoByIdVO infoById(NotNullId notNullId) {

        Long userIdSafe = UserUtil.getCurrentUserIdSafe();

        NotifyRefUserDO notifyRefUserDO =
            notifyRefUserService.lambdaQuery().eq(NotifyRefUserDO::getNotifyId, notNullId.getId())
                .select(NotifyRefUserDO::getReadFlag, NotifyRefUserDO::getUpdateTime)
                .eq(NotifyRefUserDO::getUserId, userIdSafe).one();

        // 不是自己的通知，无法查看详情
        if (notifyRefUserDO == null) {
            ApiResult.error(BaseBizCodeEnum.ILLEGAL_REQUEST);
        }

        // 对象拷贝
        NotifyInfoByIdVO infoByIdVO = BeanUtil.copyProperties(getById(notNullId.getId()), NotifyInfoByIdVO.class);

        // 赋值属性
        infoByIdVO.setReadFlag(notifyRefUserDO.getReadFlag());
        infoByIdVO.setUpdateTime(notifyRefUserDO.getUpdateTime());

        return infoByIdVO;
    }

}




